_zimfw_upgrade() {
  local -r ztarget=${__ZIMFW_FILE:A} zurl=https://github.com/zimfw/zimfw/releases/latest/download/zimfw.zsh.gz
  if [[ ! -w ${ztarget:h} ]]; then
    print -u2 -R $'<%= red %>No write permission to <%= bold %>'${ztarget:h}$'<%= normalred %>. Will not try to upgrade.<%= normal %>'
    return 1
  fi
  {
    if (( ${+commands[curl]} )); then
      command curl -fsSL -o ${ztarget}.new.gz ${zurl} || return 1
    else
      local zopt
      if (( _zprintlevel <= 1 )) zopt=-q
      if ! command wget -nv ${zopt} -O ${ztarget}.new.gz ${zurl}; then
        if (( _zprintlevel <= 1 )); then
          print -u2 -R $'<%= red %>Failed to download <%= bold %>'${zurl}$'<%= normalred %>. Use <%= bold %>-v<%= normalred %> option to see details.<%= normal %>'
        fi
        return 1
      fi
    fi
    command gunzip -f ${ztarget}.new.gz || return 1
    # .latest_version can be outdated and will yield a false warning if zimfw is
    # upgraded before .latest_version is refreshed. Bad thing about having a cache.
    _zimfw_mv ${ztarget}{.new,} && command rm -f ${ZIM_HOME}/.latest_version && \
        _zimfw_print 'Done with upgrade.'
  } always {
    command rm -f ${ztarget}.new{,.gz}
  }
}
